/* 
 * File:   Camera.cpp
 * Author: Ernest Mashele <mashern@gmail.com>
 * 
 * Created on April 12, 2011, 1:56 PM
 */

#include "Camera.h"

#define DEG_TO_RAD 0.0174532925F

Camera::Camera(D3DXVECTOR3 startPos) :
	Pos(startPos), yrot(0), xrot(0), zrot(0) {
	ymove = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
	zmove = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
	xmove = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
}

Camera::~Camera(void) {
}

void Camera::GetViewMatrix(D3DXMATRIX *View) {

	ymove = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
	zmove = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
	xmove = D3DXVECTOR3(1.0f, 0.0f, 0.0f);

	D3DXMATRIX yawMatrix;
	D3DXMatrixRotationAxis(&yawMatrix, &ymove, yrot);
	D3DXVec3TransformCoord(&zmove, &zmove, &yawMatrix);
	D3DXVec3TransformCoord(&xmove, &xmove, &yawMatrix);

	D3DXMATRIX pitchMatrix;
	D3DXMatrixRotationAxis(&pitchMatrix, &xmove, xrot);
	D3DXVec3TransformCoord(&zmove, &zmove, &pitchMatrix);
	D3DXVec3TransformCoord(&ymove, &ymove, &pitchMatrix);

	D3DXMATRIX rollMatrix;
	D3DXMatrixRotationAxis(&rollMatrix, &zmove, zrot);
	D3DXVec3TransformCoord(&xmove, &xmove, &rollMatrix);
	D3DXVec3TransformCoord(&ymove, &ymove, &rollMatrix);

	D3DXMatrixIdentity(View);
	View->_11 = xmove.x;
	View->_12 = ymove.x;
	View->_13 = zmove.x;
	View->_21 = xmove.y;
	View->_22 = ymove.y;
	View->_23 = zmove.y;
	View->_31 = xmove.z;
	View->_32 = ymove.z;
	View->_33 = zmove.z;

	View->_41 = -D3DXVec3Dot(&Pos, &xmove);
	View->_42 = -D3DXVec3Dot(&Pos, &ymove);
	View->_43 = -D3DXVec3Dot(&Pos, &zmove);
}

void Camera::Yaw(float amount) {
	yrot += amount;
	yrot = GetAngle(yrot);
}

void Camera::Pitch(float amount) {
	xrot += amount;
	xrot = GetAngle(xrot);
}

void Camera::Roll(float amount) {
	zrot += amount;
	zrot = GetAngle(zrot);
}

// restrict angle to degrees
float Camera::GetAngle(float angle) const {
	if (angle > float(2.0f * D3DX_PI))
		angle -= float(2.0f * D3DX_PI);

	if (angle < 0.0f)
		angle += float(2.0f * D3DX_PI);

	return angle;
}

void Camera::MoveForward(float amount) {
	Pos += zmove * amount;
}

void Camera::MoveRight(float amount) {
	Pos += xmove * amount;
}

void Camera::MoveUp(float amount) {
	Pos += ymove * amount;
}
